#include "Tabparser.h"
using namespace std;

void Tabparser::vec_display(vector<string> tmp)
{
    for(vector<string>::iterator it1 = tmp.begin();it1 != tmp.end();++it1)
    {
        cout << setw(8) << *it1;
    }
    cout << endl;
}
// void Tabparser::listlize(vector<string> tmp){
//     for(vector<string>::iterator it1 = tmp.begin();it1 != tmp.end();it1++)
//         cout << *it1 << ",";
//     cout << endl;
// }
vector<string> Tabparser::getlines(const string table_path)
{
    vector<string> lines;
    string line;
    ifstream fin(table_path.c_str());
    while(getline(fin,line))
    {
        lines.push_back(line);
    }
    return lines;
}
vector<ItemType> Tabparser::getschema(const string schema_path)
{
    vector<ItemType> schema;
    ifstream fin(schema_path.c_str());
    string s;
    while(fin >> s){
        if("int" == s)
            schema.push_back(ItemType_Int);
        else if("float" == s)
            schema.push_back(ItemType_Float);
        else if("char*" == s)
            schema.push_back(ItemType_String);
        else if("struct" == s)
            schema.push_back(ItemType_Struct);
        else
            schema.push_back(ItemType_Unknown);
    }
    return schema;
}
vector<string> Tabparser::split(const string& s, string separate)
{
    vector<string> items;
    int seplen = separate.size();
    int lapos = 0,index = -1;
    while(-1 != (index = s.find(separate,lapos)))
    {
        items.push_back(s.substr(lapos,index - lapos));
        lapos = index + seplen;
    }
    string laststring = s.substr(lapos);
    if(!laststring.empty())
    {
        items.push_back(laststring);
    }
    return items;
}

TObjectList * Tabparser::check(string schema_path,string table_path, Function func)
{
    vector<ItemType> schema = getschema(schema_path);
    vector<string> lines = getlines(table_path);
    for(vector<string>::iterator line_index = lines.begin();line_index != lines.end();++line_index)
    {
        vector<string> items = split((*line_index),"\t");
        TObjectList * lineObjectList = new TObjectList();
        for(int i = 0;i < items.size(); i++)
        {
            string array_str;
            int array_sign = 0;
            string item = items.at(i);
            int index = item.find(":",0);
             if(index != -1)
             {
                array_sign = 1;
             }
            switch(schema.at(i))
            {
            case ItemType_Int:
                if(array_sign != 1)
                {
                    int tmp  = atoi(item.c_str());
                    lineObjectList -> push_back(new TObject(tmp));
                }
                else
                {
                    array_str = item.substr(index + 1,item.length() - index);
                    vector<string> int_array = split(array_str,",");
                    TObjectList * tmpList = new TObjectList();
                    for(vector<string>::iterator subItem = int_array.begin(); int_array.end() != subItem; ++subItem)
                    {
                        int tmp = atoi(subItem->c_str());
                        tmpList->push_back(new TObject(tmp));
                    }
                    lineObjectList->push_back(tmpList);
                }
                break;
            case ItemType_Float:
                if(array_sign != 1)
                {
                    float tmp  = atof(item.c_str());
                    lineObjectList -> push_back(new TObject(tmp));
                }
                else
                {
                    array_str = item.substr(index + 1,item.length() - index);
                    vector<string> float_array = split(array_str,",");
                    TObjectList * tmpList = new TObjectList();
                    for(vector<string>::iterator subItem = float_array.begin(); float_array.end() != subItem; ++subItem)
                    {
                        float tmp = atof(subItem->c_str());
                        tmpList -> push_back(new TObject(tmp));
                    }
                    lineObjectList -> push_back(tmpList);
                }
                break;
            case ItemType_String:
                if(array_sign != 1)
                {
                    lineObjectList -> push_back(new TObject(item));
                }
                else{
                    array_str = item.substr(index + 1,item.length() - index);
                    vector<string> string_array = split(array_str,",");
                    TObjectList * tmpList = new TObjectList();
                    for(vector<string>::iterator subItem = string_array.begin(); string_array.end() != subItem; ++subItem)
                    {
                        tmpList -> push_back(new TObject(*subItem));
                    }
                    lineObjectList -> push_back(tmpList);
                }
                break;
            case ItemType_Struct:
                TObject * tmp = func(item);
                lineObjectList -> push_back(tmp);
                break;
            }
        }
        m_toTable->push_back(lineObjectList);
    }
    return m_toTable;
}
/*
void Tabparser::display()
{
    vector<string> schema  = getschema();
    vec_display(schema);
}*/

void Tabparser::destroy()
{
    delete m_toTable;
}
